#include <valarray>
#include <iostream>

using namespace std;

template<class T> class Slice_iter
{
    valarray<T>* v;
    slice s;
    size_t curr;
    T& ref(size_t i)const{
        return (*v)[s.start() + i*s.stride()];
    }
public:
    Slice_iter(valarray<T>* vv, slice ss):v(vv), s(ss), curr(0){}
    Slice_iter end(){
        Slice_iter t = *this;
        t.curr = s.size();
        return t;
    }
    Slice_iter& operator++(){
        curr++;
        return *this;
    }
    Slice_iter operator++(int){
        Slice_iter t = *this;
        curr++;
        return t;
    }
    T& operator*(){
        return ref(curr);
    }
    template <class T>
    friend  bool operator==(const Slice_iter<T>& p,
                            const Slice_iter<T>& q);

    template <class T>    
    friend  bool operator!=(const Slice_iter<T>& p,
                            const Slice_iter<T>& q);
    
};
template<class T> bool operator==(const Slice_iter<T>& p,
                                  const Slice_iter<T>& q)
{
    return p.curr == q.curr &&
        p.s.stride() == q.s.stride() &&
        p.s.start() == q.s.start();
}
template<class T> bool operator !=(const Slice_iter<T>& p,
                                  const Slice_iter<T>& q)
{
    return !( p == q);
}

int main(){
    int matrix[] = {0, 1, 2,
                    3, 4, 5,
                    6, 7, 8,
                    9, 10,11};
    valarray<int> mv(matrix, 12);
    slice s(0, 3, 4);
    Slice_iter<int> iter(&mv, s);
    
    for(Slice_iter<int> i = iter; i != iter.end(); ++i){
        std::cout << *i << " ";
    }
    std::cout << std::endl;
    
}

    
    
    

    
            
            
            
    
    
